Trò chơi Angry Birds trong UNITY Engine
31.709 lượt xem;
1 using UnityEngine;
2 using System.Collections;
3 using System.Collections.Generic;
4
5
6 public abstract class AbstractGoSplineSolver
7 {
8 protected List<Vector3> _nodes;
9 public List<Vector3> nodes { get { return _nodes; } }
10 protected float _pathLength;
11
12 // how many subdivisions should we divide each segment into? higher values take longer to build and lookup but
13 // result in closer to actual constant velocity
14 protected int totalSubdivisionsPerNodeForLookupTable = 5;
15 protected Dictionary<float, float> _segmentTimeForDistance; // holds data in the form [time:distance] as a lookup table
16
17
18
19 // the default implementation breaks the spline down into segments and approximates distance by adding up
20 // the length of each segment
21 public virtual void buildPath()
22 {
23 var totalSudivisions = _nodes.Count * totalSubdivisionsPerNodeForLookupTable;
24 _pathLength = 0;
25 float timePerSlice = 1f / totalSudivisions;
26
27 // we dont care about the first node for distances because they are always t:0 and len:0
28 _segmentTimeForDistance = new Dictionary<float, float>( totalSudivisions );
29
30
31 var lastPoint = getPoint( 0 );
32
33 // skip the first node and wrap 1 extra node
34 for( var i = 1; i < totalSudivisions + 1; i++ )
35 {
36 // what is the current time along the path?
37 float currentTime = timePerSlice * i;
38
39 var currentPoint = getPoint( currentTime );
40 _pathLength += Vector3.Distance( currentPoint, lastPoint );
41 lastPoint = currentPoint;
42
43 _segmentTimeForDistance.Add( currentTime, _pathLength );
44 }
45 }
46
47
48 public abstract void closePath();
49
50
51 // gets the raw point not taking into account constant speed. used for drawing gizmos
52 public abstract Vector3 getPoint( float t );
53
54
55 // gets the point taking in to account constant speed. the default implementation approximates the length of the spline
56 // by walking it and calculating the distance between each node
57 public virtual Vector3 getPointOnPath( float t )
58 {
59 // we know exactly how far along the path we want to be from the passed in t
60 var targetDistance = _pathLength * t;
61
62 // store the previous and next nodes in our lookup table
63 var previousNodeTime = 0f;
64 var previousNodeLength = 0f;
65 var nextNodeTime = 0f;
66 var nextNodeLength = 0f;
67
68 // loop through all the values in our lookup table and find the two nodes our targetDistance falls between
69 foreach( var item in _segmentTimeForDistance )
70 {
71 // have we passed our targetDistance yet?
72 if( item.Value >= targetDistance )
73 {
74 nextNodeTime = item.Key;
75 nextNodeLength = item.Value;
76
77 if( previousNodeTime > 0 )
78 previousNodeLength = _segmentTimeForDistance[previousNodeTime];
79
80 break;
81 }
82 previousNodeTime = item.Key;
83 }
84
85 // translate the values from the lookup table estimating the arc length between our known nodes from the lookup table
86 var segmentTime = nextNodeTime - previousNodeTime;
87 var segmentLength = nextNodeLength - previousNodeLength;
88 var distanceIntoSegment = targetDistance - previousNodeLength;
89
90 t = previousNodeTime + ( distanceIntoSegment / segmentLength ) * segmentTime;
91
92 return getPoint( t );
93 }
94
95
96 public void reverseNodes()
97 {
98 _nodes.Reverse();
99 }
100
101
102 public virtual void drawGizmos()
103 {}
104
105 }
2 using System.Collections;
3 using System.Collections.Generic;
4
5
6 public abstract class AbstractGoSplineSolver
7 {
8 protected List<Vector3> _nodes;
9 public List<Vector3> nodes { get { return _nodes; } }
10 protected float _pathLength;
11
12 // how many subdivisions should we divide each segment into? higher values take longer to build and lookup but
13 // result in closer to actual constant velocity
14 protected int totalSubdivisionsPerNodeForLookupTable = 5;
15 protected Dictionary<float, float> _segmentTimeForDistance; // holds data in the form [time:distance] as a lookup table
16
17
18
19 // the default implementation breaks the spline down into segments and approximates distance by adding up
20 // the length of each segment
21 public virtual void buildPath()
22 {
23 var totalSudivisions = _nodes.Count * totalSubdivisionsPerNodeForLookupTable;
24 _pathLength = 0;
25 float timePerSlice = 1f / totalSudivisions;
26
27 // we dont care about the first node for distances because they are always t:0 and len:0
28 _segmentTimeForDistance = new Dictionary<float, float>( totalSudivisions );
29
30
31 var lastPoint = getPoint( 0 );
32
33 // skip the first node and wrap 1 extra node
34 for( var i = 1; i < totalSudivisions + 1; i++ )
35 {
36 // what is the current time along the path?
37 float currentTime = timePerSlice * i;
38
39 var currentPoint = getPoint( currentTime );
40 _pathLength += Vector3.Distance( currentPoint, lastPoint );
41 lastPoint = currentPoint;
42
43 _segmentTimeForDistance.Add( currentTime, _pathLength );
44 }
45 }
46
47
48 public abstract void closePath();
49
50
51 // gets the raw point not taking into account constant speed. used for drawing gizmos
52 public abstract Vector3 getPoint( float t );
53
54
55 // gets the point taking in to account constant speed. the default implementation approximates the length of the spline
56 // by walking it and calculating the distance between each node
57 public virtual Vector3 getPointOnPath( float t )
58 {
59 // we know exactly how far along the path we want to be from the passed in t
60 var targetDistance = _pathLength * t;
61
62 // store the previous and next nodes in our lookup table
63 var previousNodeTime = 0f;
64 var previousNodeLength = 0f;
65 var nextNodeTime = 0f;
66 var nextNodeLength = 0f;
67
68 // loop through all the values in our lookup table and find the two nodes our targetDistance falls between
69 foreach( var item in _segmentTimeForDistance )
70 {
71 // have we passed our targetDistance yet?
72 if( item.Value >= targetDistance )
73 {
74 nextNodeTime = item.Key;
75 nextNodeLength = item.Value;
76
77 if( previousNodeTime > 0 )
78 previousNodeLength = _segmentTimeForDistance[previousNodeTime];
79
80 break;
81 }
82 previousNodeTime = item.Key;
83 }
84
85 // translate the values from the lookup table estimating the arc length between our known nodes from the lookup table
86 var segmentTime = nextNodeTime - previousNodeTime;
87 var segmentLength = nextNodeLength - previousNodeLength;
88 var distanceIntoSegment = targetDistance - previousNodeLength;
89
90 t = previousNodeTime + ( distanceIntoSegment / segmentLength ) * segmentTime;
91
92 return getPoint( t );
93 }
94
95
96 public void reverseNodes()
97 {
98 _nodes.Reverse();
99 }
100
101
102 public virtual void drawGizmos()
103 {}
104
105 }